import React from 'react';
import PropTypes from 'prop-types';
import { Layout, Icon, message, Modal, Form, Row, Col } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Route, Redirect, Switch, routerRedux, Link } from 'dva/router';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import { enquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.png';
import hangup1 from '../assets/hangup1.png';
import pickup1 from '../assets/pickup1.png';
import Websocket from 'react-websocket';
import { ENGINE_METHOD_DIGESTS } from 'constants';
import { Button } from 'antd/lib/radio';
import CountDown from '../components/CountDown';
import { solo } from '../common/solo';

const { Content, Header, Footer } = Layout;
const { AuthorizedRoute } = Authorized;

const userId = null;
// const webSocketUrl = `websocket://192.168.2.37:9090/websocket/${userId}`;

// const webSocketUrl = `${solo.websocket}${sessionStorage.getItem("userName")}`;

/**
 * 根据菜单取得重定向地址.
 */
const redirectData = [];
const getRedirect = (item) => {
  if (item && item.children) {
    if (item.children[0] && item.children[0].path) {
      redirectData.push({
        from: `/${item.path}`,
        to: `/${item.children[0].path}`,
      });
      item.children.forEach((children) => {
        getRedirect(children);
      });
    }
  }
};

getMenuData().forEach(getRedirect);
const query = {
  'screen-xs': {
    maxWidth: 575,
  },
  'screen-sm': {
    minWidth: 576,
    maxWidth: 767,
  },
  'screen-md': {
    minWidth: 768,
    maxWidth: 991,
  },
  'screen-lg': {
    minWidth: 992,
    maxWidth: 1199,
  },
  'screen-xl': {
    minWidth: 1200,
  },
};
let isMobile;
let websocket = null;
let webSocketUrl = null;
let lockReconnect = false;//避免重复连接
let timeoutObj = null;
/* *
 * 1.连接上之后，每秒发送一个心跳，服务器同样返回一个心跳，用来表示服务器没挂。
 * 2.断线重连（我们测试的环境是断开网络连接），断开网络后，心跳包无法发送出去，所以如果当前时间距离上次成功心跳的时间超过20秒，说明连接已经出现问题了，此时需要关闭连接。
 * 3.第一次关闭连接时websocket会尝试重连，设置了一个时间期限，10秒。10秒内如果能连上（恢复网络连接）就可以继续收发消息，连不上就关闭了，并且不会重连。
 * 4.30秒内收不到服务器消息（心跳每秒发送），我就认为服务器已经挂了，就会调用close事件，然后进入第3步  
 * 一个定时器ws.keepAliveTimer，用来每秒发送一次心跳。
 * 上次心跳成功的时间ws.last_health_time以及当前时间let time = new Date().getTime();。
 * 断开连接(websocket.close())时的时间reconnect，因为在close事件发生后需要重连10秒。
 * 是否已经重连过reconnectMark。
 * 断开连接(websocket.close())时需要保存ws对象tempWs。我曾试图ws = { ...websocket }发现会丢失绑定的事件。
 * 一个定时时间为30秒的setTimeout定时器ws.receiveMessageTimer，用来表示服务器是否在30秒内返回了消息。
 * */

enquireScreen((b) => {
  isMobile = b;
});

@Form.create()
class BasicLayout extends React.PureComponent {
  static childContextTypes = {
    location: PropTypes.object,
    breadcrumbNameMap: PropTypes.object,
  }
  state = {
    isMobile,
    modalVisible: false,
    bizId: '',
    clientUserName: '',
    clientAccount: '',
    userName: '',
    merChantName: '',
    appUserId: '',
    webUserId: ''
  };
  getChildContext() {
    const { location, routerData } = this.props;
    return {
      location,
      breadcrumbNameMap: routerData,
    };
  }
  componentDidMount() {
    enquireScreen((mobile) => {
      this.setState({
        isMobile: mobile,
      });
    });
    this.props.dispatch({
      type: 'user/fetchCurrent',
    });
  }

  componentWillReceiveProps = (nextProps) => {
    if (sessionStorage.getItem("loginSuccessful")) {
      webSocketUrl = `${solo.websocket}${sessionStorage.getItem("userId")}`;
      try {
        // console.log('WebSocket又一次连接', webSocketUrl);
        websocket = new WebSocket(webSocketUrl);
        this.init();
      } catch (e) {
        this.reconnect();
      }
    }
    // else if(websocket){
    //   websocket.close();
    // }
  }
  init = () => {
    websocket.onopen = () => {
      //心跳检测重置
      this.heartCheck.start();
    };
    websocket.onmessage = (event) => {
      if (event.data) {
        var json = (new Function('return ' + event.data))();
        if (json.type == "cancel") {
          this.setState({
            modalVisible: false,
          })
          message.warning("对方已结束视频")
        } else if (json.type == "videoSign") {
          this.setState({
            modalVisible: true,
            bizId: json.bizId,
            clientUserName: json.custName,
            merChantName: json.merChantName,
            appUserId: json.appUserId,
            webUserId: json.webUserId,
          })
        } else {
          console.log('websocket接收到消息', event.data);
        }
      }
      this.heartCheck.start();
      //拿到任何消息都说明当前连接是正常的
    }
    websocket.onclose = () => {
      // console.log('链接关闭');
      this.reconnect();
    };
    websocket.onerror = () => {
      // console.log('发生异常了');
      this.reconnect();
    };
  }

  reconnect = () => {
    if (lockReconnect) {
      return;
    };
    lockReconnect = true;
    //没连接上会一直重连，设置延迟避免请求过多
    timeoutObj && clearTimeout(timeoutObj);
    timeoutObj = setTimeout(() => {
      // console.log('从新连接');
      this.componentWillReceiveProps();
      lockReconnect = false;
    }, 4000);
  }

  heartCheck = {
    timeout: 54000, //每隔三秒发送心跳
    num: 3,  //3次心跳均未响应重连
    timeoutObj: null,
    serverTimeoutObj: null,
    start: function () {
      const userId = sessionStorage.getItem("userId");
      const _this = this;
      let _num = this.num;
      this.timeoutObj && clearTimeout(this.timeoutObj);
      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
      this.timeoutObj = setTimeout(function () {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        //onmessage拿到返回的心跳就说明连接正常
        if (websocket.readyState == 1) {
          // console.log("连接状态，发送消息保持连接", userId);
          websocket.send(JSON.stringify({
            type: "ping",
            webUserId: userId,
          }));
          _num--;
          //计算答复的超时次数
          if (_num === 0) {
            websocket.colse();
          }
        } else {
          console.log("websocket连接异常", userId);
        }
      }, this.timeout)
    }
  }


  getPageTitle() {
    const { routerData, location } = this.props;
    const { pathname } = location;
    let title = '助贷审批系统';
    if (routerData[pathname] && routerData[pathname].name) {
      title = `${routerData[pathname].name} - 助贷审批系统`;
    }
    return title;
  }
  getBashRedirect = () => {
    // According to the url parameter to redirect
    // 这里是重定向的,重定向到 url 的 redirect 参数所示地址
    const urlParams = new URL(window.location.href);

    const redirect = urlParams.searchParams.get('redirect');
    // Remove the parameters in the url
    if (redirect) {
      urlParams.searchParams.delete('redirect');
      window.history.replaceState(null, 'redirect', urlParams.href);
    } else {
      //return '/dashboard/analysis';
      // return '/user/login';
      return '/home/home-page';
    }
    return redirect;
  }
  handleMenuCollapse = (collapsed) => {
    this.props.dispatch({
      type: 'global/changeLayoutCollapsed',
      payload: collapsed,
    });
  }
  handleNoticeClear = (type) => {
    message.success(`清空了${type}`);
    this.props.dispatch({
      type: 'global/clearNotices',
      payload: type,
    });
  }
  handleMenuClick = ({ key }) => {
    if (key === 'triggerError') {
      this.props.dispatch(routerRedux.push('/exception/trigger'));
      return;
    }
    if (key === 'updataPassword') {
      this.props.dispatch(routerRedux.push('/system/updata-password'));
      return;
    }
    if (key === 'logout') {
      sessionStorage.setItem("loginSuccessful", false)
      this.props.dispatch({ type: 'login/logout', });
    }
  }
  handleNoticeVisibleChange = (visible) => {
    if (visible) {
      this.props.dispatch({
        type: 'global/fetchNotices',
      });
    }
  }
  // handleWebSocketData = (data) => {
  //   if (data) {
  //     var json = (new Function('return ' + data))();
  //     if (json.type == "cancel") {
  //       this.setState({
  //         modalVisible: false,
  //       })
  //       message.warning("对方已结束视频")
  //     } else {
  //       this.setState({
  //         modalVisible: true,
  //         // clientAccount: json.username,
  //         bizId: json.bizId,
  //         clientUserName: json.custName,
  //         merChantName: json.merChantName,
  //         appUserId: json.appUserId,
  //         webUserId: json.webUserId,
  //       })
  //     }
  //   }
  // }

  handleConnectionVideo = () => {//接听成功
    websocket.send(JSON.stringify({
      type: "pickup",
      webUserId: this.state.webUserId,
      appUserId: this.state.appUserId
    }));
    this.setState({
      modalVisible: false
    })
  }

  handleCancelVideo = () => {//拒绝接听
    websocket.send(JSON.stringify({
      type: "refuse",
      webUserId: this.state.webUserId,
      appUserId: this.state.appUserId
    }));

    this.setState({
      modalVisible: false
    })
  }

  handleTimeEnd = () => {//时间到未接听
    if (this.state.modalVisible) {
      websocket.send(JSON.stringify({
        type: "ignore",
        webUserId: this.state.webUserId,
        appUserId: this.state.appUserId
      }));
      this.setState({
        modalVisible: false
      })
    }
  }

  //websocket连接成功后
  handleOpenWebSocket = () => {

  }

  handleCloseWebSocket = () => {
    websocket.close();
  }

  render() {


    const {
      currentUser, collapsed, fetchingNotices, notices, routerData, match, location,
      menuForCurrentUser
    } = this.props;
    const bashRedirect = this.getBashRedirect();
    const url = webSocketUrl;

    const targetTime = new Date().getTime() + 30000;
    const layout = (
      menuForCurrentUser && Array.isArray(menuForCurrentUser) && menuForCurrentUser.length > 0 &&
      <Layout>
        <SiderMenu
          logo={logo}
          // 不带Authorized参数的情况下如果没有权限,会强制跳到403界面
          // If you do not have the Authorized parameter
          // you will be forced to jump to the 403 interface without permission
          Authorized={Authorized}
          menuData={menuForCurrentUser}
          // menuData={getMenuData()}
          collapsed={collapsed}
          location={location}
          isMobile={this.state.isMobile}
          onCollapse={this.handleMenuCollapse}
        />
        {/* <Websocket
          url={url}
          onOpen={this.handleOpenWebSocket}
          onClose={this.handleCloseWebSocket}
          onMessage={this.handleData.bind(this)}
        /> */}

        <Layout>
          <Header style={{ padding: 0 }}>
            <GlobalHeader
              logo={logo}
              currentUser={currentUser}
              fetchingNotices={fetchingNotices}
              notices={notices}
              collapsed={collapsed}
              isMobile={this.state.isMobile}
              onNoticeClear={this.handleNoticeClear}
              onCollapse={this.handleMenuCollapse}
              onMenuClick={this.handleMenuClick}
              onNoticeVisibleChange={this.handleNoticeVisibleChange}
            />
          </Header>
          <Content style={{ margin: '24px 24px 0', height: '100%' }}>
            <Switch>
              {
                redirectData.map(item =>
                  <Redirect key={item.from} exact from={item.from} to={item.to} />
                )
              }
              {
                getRoutes(match.path, routerData).map(item =>
                  (
                  // <div>
                  //   {console.log("AuthorizedRoute", item)}
                    <AuthorizedRoute
                      key={item.key}
                      path={item.path}
                      component={item.component}
                      exact={item.exact}
                      authority={item.authority}
                      redirectPath="/exception/403"
                    />
                  // </div>
                  )
                )
              }
              <Redirect exact from="/" to={bashRedirect} />
              <Route render={NotFound} />
            </Switch>
          </Content>
          <Footer style={{ padding: 0 }}>
            <GlobalFooter
              links={[{
                key: '助贷审批系统',
                title: '助贷审批系统',
                href: 'http://112.64.161.204:8000/#/home/home-page',
                blankTarget: true,
                // }, {
                //   key: 'github',
                //   title: <Icon type="github" />,
                //   href: 'https://github.com/ant-design/ant-design-pro',
                //   blankTarget: true,
                // }, {
                //   key: 'Ant Design',
                //   title: 'Ant Design',
                //   href: 'http://ant.design',
                //   blankTarget: true,
              }]}
              copyright={
                <div>
                  Copyright <Icon type="copyright" /> 2018 上海云钱出品
                </div>
              }
            />
          </Footer>
        </Layout>
        <Modal
          title="视频面签"
          visible={this.state.modalVisible}
          footer={null}
          keyboard={true}
          maskClosable={false}
          onCancel={this.handleCancelVideo}
        >
          <Row style={{ textAlign: 'center', fontSize: 16 }}>
            {this.state.merChantName}    {/*{this.state.clientAccount}*/}
          </Row>
          <Row style={{ textAlign: 'center', fontSize: 16, marginTop: 10 }}>
            贷款人：{this.state.clientUserName}
          </Row>
          <Row style={{ textAlign: 'center', fontSize: 18, marginTop: 20, color: 'green' }}>
            请求视频面签。。。 <CountDown style={{ fontSize: 20 }} target={targetTime} onEnd={this.handleTimeEnd} />
          </Row>
          <div style={{ textAlign: 'center', marginTop: 20 }}>
            <img src={hangup1} onClick={this.handleCancelVideo} style={{ marginRight: 40 }}></img>
            <a
              href={`${solo.videoFacePage}bizId=${this.state.bizId}&userId=${this.state.webUserId}`}
              // href={`https://wx.cloudpay.com.cn/demos/v-wh-test.html?bizId=${this.state.bizId}&username=${this.state.userName}`}
              target="_blank"
              onClick={this.handleConnectionVideo}
            >
              <img src={pickup1} style={{ marginLeft: 40 }} />
            </a>
          </div>
        </Modal>
      </Layout>
    );

    return (
      // menuForCurrentUser > 0 &&
      <DocumentTitle title={this.getPageTitle()}>
        <ContainerQuery query={query}>
          {params => <div className={classNames(params)}>{layout}</div>}
        </ContainerQuery>
      </DocumentTitle>
    );
  }
}

export default connect(({ user, global, loading }) => ({
  currentUser: user.currentUser,
  menuForCurrentUser: user.menuForCurrentUser,
  collapsed: global.collapsed,
  fetchingNotices: loading.effects['global/fetchNotices'],
  notices: global.notices,
}))(BasicLayout);

